home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / MacPNG Library 1.02 / pngMacSrc 1.02 / PNG Library 0.80 / PNGWUTIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-29  |  31.4 KB  |  1,142 lines  |  [TEXT/CWIE]

  1.  
  2. /* pngwutil.c - utilities to write a png file
  3.  
  4.    libpng 1.0 beta 2 - version 0.8
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
  7.    August 20, 1995
  8.    */
  9. #define PNG_INTERNAL
  10. #include "png.h"
  11.  
  12. /* place a 32 bit number into a buffer in png byte order.  We work
  13.    with unsigned numbers for convenience, you may have to cast
  14.    signed numbers (if you use any, most png data is unsigned). */
  15. void
  16. png_save_uint_32(png_byte *buf, png_uint_32 i)
  17. {
  18.    buf[0] = (png_byte)((i >> 24) & 0xff);
  19.    buf[1] = (png_byte)((i >> 16) & 0xff);
  20.    buf[2] = (png_byte)((i >> 8) & 0xff);
  21.    buf[3] = (png_byte)(i & 0xff);
  22. }
  23.  
  24. /* place a 16 bit number into a buffer in png byte order */
  25. void
  26. png_save_uint_16(png_byte *buf, png_uint_16 i)
  27. {
  28.    buf[0] = (png_byte)((i >> 8) & 0xff);
  29.    buf[1] = (png_byte)(i & 0xff);
  30. }
  31.  
  32. /* write a 32 bit number */
  33. void
  34. png_write_uint_32(png_struct *png_ptr, png_uint_32 i)
  35. {
  36.    png_byte buf[4];
  37.  
  38.    buf[0] = (png_byte)((i >> 24) & 0xff);
  39.    buf[1] = (png_byte)((i >> 16) & 0xff);
  40.    buf[2] = (png_byte)((i >> 8) & 0xff);
  41.    buf[3] = (png_byte)(i & 0xff);
  42.    png_write_data(png_ptr, buf, 4);
  43. }
  44.  
  45. /* write a 16 bit number */
  46. void
  47. png_write_uint_16(png_struct *png_ptr, png_uint_16 i)
  48. {
  49.    png_byte buf[2];
  50.  
  51.    buf[0] = (png_byte)((i >> 8) & 0xff);
  52.    buf[1] = (png_byte)(i & 0xff);
  53.    png_write_data(png_ptr, buf, 2);
  54. }
  55.  
  56. /* Write a png chunk all at once.  The type is an array of ASCII characters
  57.    representing the chunk name.  The array must be at least 4 bytes in
  58.    length, and does not need to be null terminated.  To be safe, pass the
  59.    pre-defined chunk names here, and if you need a new one, define it
  60.    where the others are defined.  The length is the length of the data.
  61.    All the data must be present.  If that is not possible, use the
  62.    png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
  63.    functions instead.  */
  64. void
  65. png_write_chunk(png_struct *png_ptr, png_byte *type,
  66.    png_byte *data, png_uint_32 length)
  67. {
  68.    /* write length */
  69.    png_write_uint_32(png_ptr, length);
  70.    /* write chunk name */
  71.    png_write_data(png_ptr, type, (png_uint_32)4);
  72.    /* reset the crc and run the chunk name over it */
  73.    png_reset_crc(png_ptr);
  74.    png_calculate_crc(png_ptr, type, (png_uint_32)4);
  75.    /* write the data and update the crc */
  76.    if (length)
  77.    {
  78.       png_calculate_crc(png_ptr, data, length);
  79.       png_write_data(png_ptr, data, length);
  80.    }
  81.    /* write the crc */
  82.    png_write_uint_32(png_ptr, ~png_ptr->crc);
  83. }
  84.  
  85. /* Write the start of a png chunk.  The type is the chunk type.
  86.    The total_length is the sum of the lengths of all the data you will be
  87.    passing in png_write_chunk_data() */
  88. void
  89. png_write_chunk_start(png_struct *png_ptr, png_byte *type,
  90.    png_uint_32 total_length)
  91. {
  92.    /* write the length */
  93.    png_write_uint_32(png_ptr, total_length);
  94.    /* write the chunk name */
  95.    png_write_data(png_ptr, type, (png_uint_32)4);
  96.    /* reset the crc and run it over the chunk name */
  97.    png_reset_crc(png_ptr);
  98.    png_calculate_crc(png_ptr, type, (png_uint_32)4);
  99. }
  100.  
  101. /* write the data of a png chunk started with png_write_chunk_start().
  102.    Note that multiple calls to this function are allowed, and that the
  103.    sum of the lengths from these calls *must* add up to the total_length
  104.    given to png_write_chunk_start() */
  105. void
  106. png_write_chunk_data(png_struct *png_ptr, png_byte *data, png_uint_32 length)
  107. {
  108.    /* write the data, and run the crc over it */
  109.    if (length)
  110.    {
  111.       png_calculate_crc(png_ptr, data, length);
  112.       png_write_data(png_ptr, data, length);
  113.    }
  114. }
  115.  
  116. /* finish a chunk started with png_write_chunk_start() */
  117. void
  118. png_write_chunk_end(png_struct *png_ptr)
  119. {
  120.    /* write the crc */
  121.    png_write_uint_32(png_ptr, ~png_ptr->crc);
  122. }
  123.  
  124. /* simple function to write the signature */
  125. void
  126. png_write_sig(png_struct *png_ptr)
  127. {
  128.    /* write the 8 byte signature */
  129.    png_write_data(png_ptr, png_sig, (png_uint_32)8);
  130. }
  131.  
  132. /* Write the IHDR chunk, and update the png_struct with the necessary
  133.    information.  Note that the rest of this code depends upon this
  134.    information being correct.  */
  135. void
  136. png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height,
  137.    int bit_depth, int color_type, int compression_type, int filter_type,
  138.    int interlace_type)
  139. {
  140.    png_byte buf[13]; /* buffer to store the IHDR info */
  141.  
  142.    /* pack the header information into the buffer */
  143.    png_save_uint_32(buf, width);
  144.    png_save_uint_32(buf + 4, height);
  145.    buf[8] = bit_depth;
  146.    buf[9] = color_type;
  147.    buf[10] = compression_type;
  148.    buf[11] = filter_type;
  149.    buf[12] = interlace_type;
  150.    /* save off the relevent information */
  151.    png_ptr->bit_depth = bit_depth;
  152.    png_ptr->color_type = color_type;
  153.    png_ptr->interlaced = interlace_type;
  154.    png_ptr->width = width;
  155.    png_ptr->height = height;
  156.  
  157.    switch (color_type)
  158.    {
  159.       case 0:
  160.       case 3:
  161.          png_ptr->channels = 1;
  162.          break;
  163.       case 2:
  164.          png_ptr->channels = 3;
  165.          break;
  166.       case 4:
  167.          png_ptr->channels = 2;
  168.          break;
  169.       case 6:
  170.          png_ptr->channels = 4;
  171.          break;
  172.    }
  173.    png_ptr->pixel_depth = bit_depth * png_ptr->channels;
  174.    png_ptr->rowbytes = ((width * (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
  175.    /* set the usr info, so any transformations can modify it */
  176.    png_ptr->usr_width = png_ptr->width;
  177.    png_ptr->usr_bit_depth = png_ptr->bit_depth;
  178.     png_ptr->usr_channels = png_ptr->channels;
  179.  
  180.    /* write the chunk */
  181.    png_write_chunk(png_ptr, png_IHDR, buf, (png_uint_32)13);
  182.  
  183.    /* initialize zlib with png info */
  184.    png_ptr->zstream = &(png_ptr->zstream_struct);
  185.    png_ptr->zstream->zalloc = png_zalloc;
  186.    png_ptr->zstream->zfree = png_zfree;
  187.    png_ptr->zstream->opaque = (voidp)png_ptr;
  188.    if (!png_ptr->do_custom_filter)
  189.    {
  190.       if (png_ptr->color_type == 3 || png_ptr->bit_depth < 8)
  191.          png_ptr->do_filter = 0;
  192.       else
  193.          png_ptr->do_filter = 1;
  194.    }
  195.    if (!png_ptr->zlib_custom_strategy)
  196.    {
  197.       if (png_ptr->do_filter)
  198.          png_ptr->zlib_strategy = Z_FILTERED;
  199.       else
  200.          png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
  201.    }
  202.    if (!png_ptr->zlib_custom_level)
  203.       png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
  204.    if (!png_ptr->zlib_custom_mem_level)
  205.       png_ptr->zlib_mem_level = 8;
  206.    if (!png_ptr->zlib_custom_window_bits)
  207.       png_ptr->zlib_window_bits = 15;
  208.    if (!png_ptr->zlib_custom_method)
  209.       png_ptr->zlib_method = 8;
  210.    deflateInit2(png_ptr->zstream, png_ptr->zlib_level,
  211.       png_ptr->zlib_method,
  212.       png_ptr->zlib_window_bits,
  213.       png_ptr->zlib_mem_level,
  214.       png_ptr->zlib_strategy);
  215.    png_ptr->zstream->next_out = png_ptr->zbuf;
  216.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  217.  
  218. }
  219.  
  220. /* write the palette.  We are careful not to trust png_color to be in the
  221.    correct order for PNG, so people can redefine it to any convient
  222.    structure. */
  223. void
  224. png_write_PLTE(png_struct *png_ptr, png_color *palette, int number)
  225. {
  226.    int i;
  227.    png_color *pal_ptr;
  228.    png_byte buf[3];
  229.  
  230.    png_write_chunk_start(png_ptr, png_PLTE, number * 3);
  231.    for (i = 0, pal_ptr = palette;
  232.       i < number;
  233.       i++, pal_ptr++)
  234.    {
  235.       buf[0] = pal_ptr->red;
  236.       buf[1] = pal_ptr->green;
  237.       buf[2] = pal_ptr->blue;
  238.       png_write_chunk_data(png_ptr, buf, (png_uint_32)3);
  239.    }
  240.    png_write_chunk_end(png_ptr);
  241. }
  242.  
  243. /* write an IDAT chunk */
  244. void
  245. png_write_IDAT(png_struct *png_ptr, png_byte *data, png_uint_32 length)
  246. {
  247.    png_write_chunk(png_ptr, png_IDAT, data, length);
  248. }
  249.  
  250. /* write an IEND chunk */
  251. void
  252. png_write_IEND(png_struct *png_ptr)
  253. {
  254.    png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0);
  255. }
  256.  
  257. #if defined(PNG_WRITE_gAMA_SUPPORTED)
  258. /* write a gAMA chunk */
  259. void
  260. png_write_gAMA(png_struct *png_ptr, float gamma)
  261. {
  262.    png_uint_32 igamma;
  263.    png_byte buf[4];
  264.  
  265.    /* gamma is saved in 1/100,000ths */
  266.    igamma = (png_uint_32)(gamma * 100000.0 + 0.5);
  267.    png_save_uint_32(buf, igamma);
  268.    png_write_chunk(png_ptr, png_gAMA, buf, (png_uint_32)4);
  269. }
  270. #endif
  271.  
  272. #if defined(PNG_WRITE_sBIT_SUPPORTED)
  273. /* write the sBIT chunk */
  274. void
  275. png_write_sBIT(png_struct *png_ptr, png_color_8 *sbit, int color_type)
  276. {
  277.    png_byte buf[4];
  278.    int size;
  279.  
  280.    /* make sure we don't depend upon the order of png_color_8 */
  281.    if (color_type & PNG_COLOR_MASK_COLOR)
  282.    {
  283.       buf[0] = sbit->red;
  284.       buf[1] = sbit->green;
  285.       buf[2] = sbit->blue;
  286.       size = 3;
  287.    }
  288.    else
  289.    {
  290.       buf[0] = sbit->gray;
  291.       size = 1;
  292.    }
  293.  
  294.    if (color_type & PNG_COLOR_MASK_ALPHA)
  295.    {
  296.       buf[size++] = sbit->alpha;
  297.    }
  298.  
  299.    png_write_chunk(png_ptr, png_sBIT, buf, (png_uint_32)size);
  300. }
  301. #endif
  302.  
  303. #if defined(PNG_WRITE_cHRM_SUPPORTED)
  304. /* write the cHRM chunk */
  305. void
  306. png_write_cHRM(png_struct *png_ptr, float white_x, float white_y,
  307.    float red_x, float red_y, float green_x, float green_y,
  308.    float blue_x, float blue_y)
  309. {
  310.    png_uint_32 itemp;
  311.    png_byte buf[32];
  312.  
  313.    /* each value is saved int 1/100,000ths */
  314.    itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
  315.    png_save_uint_32(buf, itemp);
  316.    itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
  317.    png_save_uint_32(buf + 4, itemp);
  318.    itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
  319.    png_save_uint_32(buf + 8, itemp);
  320.    itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
  321.    png_save_uint_32(buf + 12, itemp);
  322.    itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
  323.    png_save_uint_32(buf + 16, itemp);
  324.    itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
  325.    png_save_uint_32(buf + 20, itemp);
  326.    itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
  327.    png_save_uint_32(buf + 24, itemp);
  328.    itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
  329.    png_save_uint_32(buf + 28, itemp);
  330.    png_write_chunk(png_ptr, png_cHRM, buf, (png_uint_32)32);
  331. }
  332. #endif
  333.  
  334. #if defined(PNG_WRITE_tRNS_SUPPORTED)
  335. /* write the tRNS chunk */
  336. void
  337. png_write_tRNS(png_struct *png_ptr, png_byte *trans, png_color_16 *tran,
  338.    int num_trans, int color_type)
  339. {
  340.    png_byte buf[6];
  341.  
  342.    if (color_type == PNG_COLOR_TYPE_PALETTE)
  343.    {
  344.       /* write the chunk out as it is */
  345.       png_write_chunk(png_ptr, png_tRNS, trans, (png_uint_32)num_trans);
  346.    }
  347.    else if (color_type == PNG_COLOR_TYPE_GRAY)
  348.    {
  349.       /* one 16 bit value */
  350.       png_save_uint_16(buf, tran->gray);
  351.       png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)2);
  352.    }
  353.    else if (color_type == PNG_COLOR_TYPE_RGB)
  354.    {
  355.       /* three 16 bit values */
  356.       png_save_uint_16(buf, tran->red);
  357.       png_save_uint_16(buf + 2, tran->green);
  358.       png_save_uint_16(buf + 4, tran->blue);
  359.       png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)6);
  360.    }
  361. }
  362. #endif
  363.  
  364. #if defined(PNG_WRITE_bKGD_SUPPORTED)
  365. /* write the background chunk */
  366. void
  367. png_write_bKGD(png_struct *png_ptr, png_color_16 *back, int color_type)
  368. {
  369.    png_byte buf[6];
  370.  
  371.    if (color_type == PNG_COLOR_TYPE_PALETTE)
  372.    {
  373.       buf[0] = back->index;
  374.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)1);
  375.    }
  376.    else if (color_type & PNG_COLOR_MASK_COLOR)
  377.    {
  378.       png_save_uint_16(buf, back->red);
  379.       png_save_uint_16(buf + 2, back->green);
  380.       png_save_uint_16(buf + 4, back->blue);
  381.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
  382.    }
  383.    else
  384.    {
  385.       png_save_uint_16(buf, back->gray);
  386.       png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
  387.    }
  388. }
  389. #endif
  390.  
  391. #if defined(PNG_WRITE_hIST_SUPPORTED)
  392. /* write the histogram */
  393. void
  394. png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number)
  395. {
  396.    int i;
  397.    png_byte buf[3];
  398.  
  399.    png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
  400.    for (i = 0; i < number; i++)
  401.    {
  402.       png_save_uint_16(buf, hist[i]);
  403.       png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
  404.    }
  405.    png_write_chunk_end(png_ptr);
  406. }
  407. #endif
  408.  
  409. #if defined(PNG_WRITE_tEXt_SUPPORTED)
  410. /* write a tEXt chunk */
  411. void
  412. png_write_tEXt(png_struct *png_ptr, char *key, char *text,
  413.    png_uint_32 text_len)
  414. {
  415.    int key_len;
  416.  
  417.    key_len = strlen(key);
  418.    /* make sure we count the 0 after the key */
  419.    png_write_chunk_start(png_ptr, png_tEXt,
  420.       (png_uint_32)(key_len + text_len + 1));
  421.    /* key has an 0 at the end.  How nice */
  422.    png_write_chunk_data(png_ptr, (png_byte *)key, (png_uint_32)(key_len + 1));
  423.    if (text && text_len)
  424.       png_write_chunk_data(png_ptr, (png_byte *)text, (png_uint_32)text_len);
  425.    png_write_chunk_end(png_ptr);
  426. }
  427. #endif
  428.  
  429. #if defined(PNG_WRITE_zTXt_SUPPORTED)
  430. /* write a compressed chunk */
  431. void
  432. png_write_zTXt(png_struct *png_ptr, char *key, char *text,
  433.    png_uint_32 text_len, int compression)
  434. {
  435.    int key_len;
  436.    char buf[1];
  437.    int i, ret;
  438.    char **output_ptr = NULL; /* array of pointers to output */
  439.    int num_output_ptr = 0; /* number of output pointers used */
  440.    int max_output_ptr = 0; /* size of output_ptr */
  441.  
  442.    key_len = strlen(key);
  443.  
  444.    /* we can't write the chunk until we find out how much data we have,
  445.       which means we need to run the compresser first, and save the
  446.       output.  This shouldn't be a problem, as the vast majority of
  447.       comments should be reasonable, but we will set up an array of
  448.       malloced pointers to be sure. */
  449.  
  450.    /* set up the compression buffers */
  451.    png_ptr->zstream->avail_in = (uInt)text_len;
  452.    png_ptr->zstream->next_in = (Byte *)text;
  453.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  454.    png_ptr->zstream->next_out = (Byte *)png_ptr->zbuf;
  455.  
  456.    /* this is the same compression loop as in png_write_row() */
  457.    do
  458.    {
  459.       /* compress the data */
  460.       ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
  461.       if (ret != Z_OK)
  462.       {
  463.          /* error */
  464.          if (png_ptr->zstream->msg)
  465.             png_error(png_ptr, png_ptr->zstream->msg);
  466.          else
  467.             png_error(png_ptr, "zlib error");
  468.       }
  469.       /* check to see if we need more room */
  470.       if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in)
  471.       {
  472.          /* make sure the output array has room */
  473.          if (num_output_ptr >= max_output_ptr)
  474.          {
  475.             png_uint_32 old_max;
  476.  
  477.             old_max = max_output_ptr;
  478.             max_output_ptr = num_output_ptr + 4;
  479.             if (output_ptr)
  480.                output_ptr = png_realloc(png_ptr, output_ptr,
  481.                   max_output_ptr * sizeof (char *),
  482.                   old_max * sizeof (char *));
  483.             else
  484.                output_ptr = png_malloc(png_ptr,
  485.                   max_output_ptr * sizeof (char *));
  486.          }
  487.  
  488.          /* save the data */
  489.          output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
  490.             png_ptr->zbuf_size);
  491.          memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
  492.             (png_size_t)png_ptr->zbuf_size);
  493.          num_output_ptr++;
  494.  
  495.          /* and reset the buffer */
  496.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  497.          png_ptr->zstream->next_out = png_ptr->zbuf;
  498.       }
  499.    /* continue until we don't have anymore to compress */
  500.    } while (png_ptr->zstream->avail_in);
  501.  
  502.    /* finish the compression */
  503.    do
  504.    {
  505.       /* tell zlib we are finished */
  506.       ret = deflate(png_ptr->zstream, Z_FINISH);
  507.       if (ret != Z_OK && ret != Z_STREAM_END)
  508.       {
  509.          /* we got an error */
  510.          if (png_ptr->zstream->msg)
  511.             png_error(png_ptr, png_ptr->zstream->msg);
  512.          else
  513.             png_error(png_ptr, "zlib error");
  514.       }
  515.  
  516.       /* check to see if we need more room */
  517.       if (!png_ptr->zstream->avail_out && ret == Z_OK)
  518.       {
  519.          /* check to make sure our output array has room */
  520.          if (num_output_ptr >= max_output_ptr)
  521.          {
  522.             png_uint_32 old_max;
  523.  
  524.             old_max = max_output_ptr;
  525.             max_output_ptr = num_output_ptr + 4;
  526.             if (output_ptr)
  527.                output_ptr = png_realloc(png_ptr, output_ptr,
  528.                   max_output_ptr * sizeof (char *),
  529.                   old_max * sizeof (char *));
  530.             else
  531.                output_ptr = png_malloc(png_ptr,
  532.                   max_output_ptr * sizeof (char *));
  533.          }
  534.  
  535.          /* save off the data */
  536.          output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
  537.             png_ptr->zbuf_size);
  538.          memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
  539.             (png_size_t)png_ptr->zbuf_size);
  540.          num_output_ptr++;
  541.  
  542.          /* and reset the buffer pointers */
  543.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  544.          png_ptr->zstream->next_out = png_ptr->zbuf;
  545.       }
  546.    } while (ret != Z_STREAM_END);
  547.  
  548.    /* text length is number of buffers plus last buffer */
  549.    text_len = png_ptr->zbuf_size * num_output_ptr;
  550.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  551.       text_len += (png_uint_32)(png_ptr->zbuf_size -
  552.          png_ptr->zstream->avail_out);
  553.  
  554.    /* write start of chunk */
  555.    png_write_chunk_start(png_ptr, png_zTXt,
  556.       (png_uint_32)(key_len + text_len + 2));
  557.    /* write key */
  558.    png_write_chunk_data(png_ptr, (png_byte *)key, (png_uint_32)(key_len + 1));
  559.    buf[0] = compression;
  560.    /* write compression */
  561.    png_write_chunk_data(png_ptr, (png_byte *)buf, (png_uint_32)1);
  562.  
  563.    /* write saved output buffers, if any */
  564.    for (i = 0; i < num_output_ptr; i++)
  565.    {
  566.       png_write_chunk_data(png_ptr, (png_byte *)output_ptr[i], png_ptr->zbuf_size);
  567.       png_large_free(png_ptr, output_ptr[i]);
  568.    }
  569.    if (max_output_ptr)
  570.       png_free(png_ptr, output_ptr);
  571.    /* write anything left in zbuf */
  572.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  573.       png_write_chunk_data(png_ptr, png_ptr->zbuf,
  574.          png_ptr->zbuf_size - png_ptr->zstream->avail_out);
  575.    /* close the chunk */
  576.    png_write_chunk_end(png_ptr);
  577.  
  578.    /* reset zlib for another zTXt or the image data */
  579.    deflateReset(png_ptr->zstream);
  580. }
  581. #endif
  582.  
  583. #if defined(PNG_WRITE_pHYs_SUPPORTED)
  584. /* write the pHYs chunk */
  585. void
  586. png_write_pHYs(png_struct *png_ptr, png_uint_32 x_pixels_per_unit,
  587.    png_uint_32 y_pixels_per_unit,
  588.    int unit_type)
  589. {
  590.    png_byte buf[9];
  591.  
  592.    png_save_uint_32(buf, x_pixels_per_unit);
  593.    png_save_uint_32(buf + 4, y_pixels_per_unit);
  594.    buf[8] = unit_type;
  595.  
  596.    png_write_chunk(png_ptr, png_pHYs, buf, (png_uint_32)9);
  597. }
  598. #endif
  599.  
  600. #if defined(PNG_WRITE_oFFs_SUPPORTED)
  601. /* write the oFFs chunk */
  602. void
  603. png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset,
  604.    png_uint_32 y_offset,
  605.    int unit_type)
  606. {
  607.    png_byte buf[9];
  608.  
  609.    png_save_uint_32(buf, x_offset);
  610.    png_save_uint_32(buf + 4, y_offset);
  611.    buf[8] = unit_type;
  612.  
  613.    png_write_chunk(png_ptr, png_oFFs, buf, (png_uint_32)9);
  614. }
  615. #endif
  616.  
  617. #if defined(PNG_WRITE_tIME_SUPPORTED)
  618. /* write the tIME chunk.  Use either png_convert_from_struct_tm()
  619.    or png_convert_from_time_t(), or fill in the structure yourself */
  620. void
  621. png_write_tIME(png_struct *png_ptr, png_time *mod_time)
  622. {
  623.    png_byte buf[7];
  624.  
  625.    png_save_uint_16(buf, mod_time->year);
  626.    buf[2] = mod_time->month;
  627.    buf[3] = mod_time->day;
  628.    buf[4] = mod_time->hour;
  629.    buf[5] = mod_time->minute;
  630.    buf[6] = mod_time->second;
  631.  
  632.    png_write_chunk(png_ptr, png_tIME, buf, (png_uint_32)7);
  633. }
  634. #endif
  635.  
  636. /* initializes the row writing capability of libpng */
  637. void
  638. png_write_start_row(png_struct *png_ptr)
  639. {
  640.    /* set up row buffer */
  641.    png_ptr->row_buf = (png_byte *)png_large_malloc(png_ptr,
  642.       (((png_uint_32)png_ptr->usr_channels *
  643.       (png_uint_32)png_ptr->usr_bit_depth *
  644.       png_ptr->width) >> 3) + 1);
  645.    /* set up filtering buffers, if filtering */
  646.    if (png_ptr->do_filter)
  647.    {
  648.       png_ptr->prev_row = (png_byte *)png_large_malloc(png_ptr,
  649.          png_ptr->rowbytes + 1);
  650.       memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  651.       png_ptr->save_row = (png_byte *)png_large_malloc(png_ptr,
  652.          png_ptr->rowbytes + 1);
  653.       memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  654.    }
  655.  
  656.    /* if interlaced, we need to set up width and height of pass */
  657.    if (png_ptr->interlaced)
  658.    {
  659.       if (!(png_ptr->transformations & PNG_INTERLACE))
  660.       {
  661.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  662.             png_pass_ystart[0]) / png_pass_yinc[0];
  663.          png_ptr->usr_width = (png_ptr->width +
  664.             png_pass_inc[0] - 1 -
  665.             png_pass_start[0]) /
  666.             png_pass_inc[0];
  667.       }
  668.       else
  669.       {
  670.          png_ptr->num_rows = png_ptr->height;
  671.          png_ptr->usr_width = png_ptr->width;
  672.       }
  673.    }
  674.    else
  675.    {
  676.       png_ptr->num_rows = png_ptr->height;
  677.       png_ptr->usr_width = png_ptr->width;
  678.    }
  679.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  680.    png_ptr->zstream->next_out = png_ptr->zbuf;
  681. }
  682.  
  683. /* Internal use only.   Called when finished processing a row of data */
  684. void
  685. png_write_finish_row(png_struct *png_ptr)
  686. {
  687.    int ret;
  688.  
  689.    /* next row */
  690.    png_ptr->row_number++;
  691.    /* see if we are done */
  692.    if (png_ptr->row_number < png_ptr->num_rows)
  693.       return;
  694.  
  695.    /* if interlaced, go to next pass */
  696.    if (png_ptr->interlaced)
  697.    {
  698.       png_ptr->row_number = 0;
  699.       if (png_ptr->transformations & PNG_INTERLACE)
  700.       {
  701.          png_ptr->pass++;
  702.       }
  703.       else
  704.       {
  705.          /* loop until we find a non-zero width or height pass */
  706.          do
  707.          {
  708.             png_ptr->pass++;
  709.             if (png_ptr->pass >= 7)
  710.                break;
  711.             png_ptr->usr_width = (png_ptr->width +
  712.                png_pass_inc[png_ptr->pass] - 1 -
  713.                png_pass_start[png_ptr->pass]) /
  714.                png_pass_inc[png_ptr->pass];
  715.             png_ptr->num_rows = (png_ptr->height +
  716.                png_pass_yinc[png_ptr->pass] - 1 -
  717.                png_pass_ystart[png_ptr->pass]) /
  718.                png_pass_yinc[png_ptr->pass];
  719.             if (png_ptr->transformations & PNG_INTERLACE)
  720.                break;
  721.          } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
  722.  
  723.       }
  724.  
  725.       /* reset filter row */
  726.       if (png_ptr->prev_row)
  727.          memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  728.       /* if we have more data to get, go get it */
  729.       if (png_ptr->pass < 7)
  730.          return;
  731.    }
  732.  
  733.    /* if we get here, we've just written the last row, so we need
  734.       to flush the compressor */
  735.    do
  736.    {
  737.       /* tell the compressor we are done */
  738.       ret = deflate(png_ptr->zstream, Z_FINISH);
  739.       /* check for an error */
  740.       if (ret != Z_OK && ret != Z_STREAM_END)
  741.       {
  742.          if (png_ptr->zstream->msg)
  743.             png_error(png_ptr, png_ptr->zstream->msg);
  744.          else
  745.             png_error(png_ptr, "zlib error");
  746.       }
  747.       /* check to see if we need more room */
  748.       if (!png_ptr->zstream->avail_out && ret == Z_OK)
  749.       {
  750.          png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  751.          png_ptr->zstream->next_out = png_ptr->zbuf;
  752.          png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  753.       }
  754.    } while (ret != Z_STREAM_END);
  755.  
  756.    /* write any extra space */
  757.    if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
  758.    {
  759.       png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
  760.          png_ptr->zstream->avail_out);
  761.    }
  762.  
  763.    deflateReset(png_ptr->zstream);
  764. }
  765.  
  766. #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
  767. /* pick out the correct pixels for the interlace pass.
  768.  
  769.    The basic idea here is to go through the row with a source
  770.    pointer and a destination pointer (sp and dp), and copy the
  771.    correct pixels for the pass.  As the row gets compacted,
  772.    sp will always be >= dp, so we should never overwrite anything.
  773.    See the default: case for the easiest code to understand.
  774.    */
  775. void
  776. png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass)
  777. {
  778.    /* we don't have to do anything on the last pass (6) */
  779.    if (row && row_info && pass < 6)
  780.    {
  781.       /* each pixel depth is handled seperately */
  782.       switch (row_info->pixel_depth)
  783.       {
  784.          case 1:
  785.          {
  786.             png_byte *sp;
  787.             png_byte *dp;
  788.             int shift;
  789.             int d;
  790.             int value;
  791.             png_uint_32 i;
  792.  
  793.             dp = row;
  794.             d = 0;
  795.             shift = 7;
  796.             for (i = png_pass_start[pass];
  797.                i < row_info->width;
  798.                i += png_pass_inc[pass])
  799.             {
  800.                sp = row + (png_size_t)(i >> 3);
  801.                value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
  802.                d |= (value << shift);
  803.  
  804.                if (shift == 0)
  805.                {
  806.                   shift = 7;
  807.                   *dp++ = d;
  808.                   d = 0;
  809.                }
  810.                else
  811.                   shift--;
  812.  
  813.             }
  814.             if (shift != 7)
  815.                *dp = d;
  816.             break;
  817.          }
  818.          case 2:
  819.          {
  820.             png_byte *sp;
  821.             png_byte *dp;
  822.             int shift;
  823.             int d;
  824.             int value;
  825.             png_uint_32 i;
  826.  
  827.             dp = row;
  828.             shift = 6;
  829.             d = 0;
  830.             for (i = png_pass_start[pass];
  831.                i < row_info->width;
  832.                i += png_pass_inc[pass])
  833.             {
  834.                sp = row + (png_size_t)(i >> 2);
  835.                value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
  836.                d |= (value << shift);
  837.  
  838.                if (shift == 0)
  839.                {
  840.                   shift = 6;
  841.                   *dp++ = d;
  842.                   d = 0;
  843.                }
  844.                else
  845.                   shift -= 2;
  846.             }
  847.             if (shift != 6)
  848.                    *dp = d;
  849.             break;
  850.          }
  851.          case 4:
  852.          {
  853.             png_byte *sp;
  854.             png_byte *dp;
  855.             int shift;
  856.             int d;
  857.             int value;
  858.             png_uint_32 i;
  859.  
  860.             dp = row;
  861.             shift = 4;
  862.             d = 0;
  863.             for (i = png_pass_start[pass];
  864.                i < row_info->width;
  865.                i += png_pass_inc[pass])
  866.             {
  867.                sp = row + (png_size_t)(i >> 1);
  868.                value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
  869.                d |= (value << shift);
  870.  
  871.                if (shift == 0)
  872.                {
  873.                   shift = 4;
  874.                   *dp++ = d;
  875.                   d = 0;
  876.                }
  877.                else
  878.                   shift -= 4;
  879.             }
  880.             if (shift != 4)
  881.                *dp = d;
  882.             break;
  883.          }
  884.          default:
  885.          {
  886.             png_byte *sp;
  887.             png_byte *dp;
  888.             png_uint_32 i;
  889.             int pixel_bytes;
  890.  
  891.             /* start at the beginning */
  892.             dp = row;
  893.             /* find out how many bytes each pixel takes up */
  894.             pixel_bytes = (row_info->pixel_depth >> 3);
  895.             /* loop through the row, only looking at the pixels that
  896.                matter */
  897.             for (i = png_pass_start[pass];
  898.                i < row_info->width;
  899.                i += png_pass_inc[pass])
  900.             {
  901.                /* find out where the original pixel is */
  902.                sp = row + (png_size_t)(i * pixel_bytes);
  903.                /* move the pixel */
  904.                if (dp != sp)
  905.                   memcpy(dp, sp, pixel_bytes);
  906.                /* next pixel */
  907.                dp += pixel_bytes;
  908.             }
  909.             break;
  910.          }
  911.       }
  912.       /* set new row width */
  913.       row_info->width = (row_info->width +
  914.          png_pass_inc[pass] - 1 -
  915.          png_pass_start[pass]) /
  916.          png_pass_inc[pass];
  917.       row_info->rowbytes = ((row_info->width *
  918.          row_info->pixel_depth + 7) >> 3);
  919.  
  920.    }
  921. }
  922. #endif
  923.  
  924. /* this filters the row.  Both row and prev_row have space at the
  925.    first byte for the filter byte. */
  926. void
  927. png_write_filter_row(png_row_info *row_info, png_byte *row,
  928.    png_byte *prev_row)
  929. {
  930.    int minf, bpp;
  931.    png_uint_32 i, v;
  932.    png_uint_32 s0, s1, s2, s3, s4, mins;
  933.    png_byte *rp, *pp, *cp, *lp;
  934.  
  935.    /* find out how many bytes offset each pixel is */
  936.    bpp = (row_info->pixel_depth + 7) / 8;
  937.    if (bpp < 1)
  938.       bpp = 1;
  939.  
  940.    /* the prediction method we use is to find which method provides
  941.       the smallest value when summing the abs of the distances from
  942.       zero using anything >= 128 as negitive numbers. */
  943.    s0 = s1 = s2 = s3 = s4 = 0;
  944.  
  945.    for (i = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp,
  946.          cp = prev_row + 1 - bpp;
  947.       i < bpp; i++, rp++, pp++, lp++, cp++)
  948.    {
  949.       /* check none filter */
  950.       v = *rp;
  951.       if (v < 128)
  952.          s0 += v;
  953.       else
  954.          s0 += 256 - v;
  955.  
  956.       /* check up filter */
  957.       v = (png_byte)(((int)*rp - (int)*pp) & 0xff);
  958.  
  959.       if (v < 128)
  960.          s2 += v;
  961.       else
  962.          s2 += 256 - v;
  963.  
  964.       /* check avg filter */
  965.       v = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
  966.  
  967.       if (v < 128)
  968.          s3 += v;
  969.       else
  970.          s3 += 256 - v;
  971.    }
  972.  
  973.    /* some filters are same until we get past bpp */
  974.    s1 = s0;
  975.    s4 = s2;
  976.  
  977.    for (; i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
  978.    {
  979.       int a, b, c, pa, pb, pc, p;
  980.  
  981.       /* check none filter */
  982.       v = *rp;
  983.       if (v < 128)
  984.          s0 += v;
  985.       else
  986.          s0 += 256 - v;
  987.  
  988.       /* check sub filter */
  989.       v = (png_byte)(((int)*rp - (int)*lp) & 0xff);
  990.  
  991.       if (v < 128)
  992.          s1 += v;
  993.       else
  994.          s1 += 256 - v;
  995.  
  996.       /* check up filter */
  997.       v = (png_byte)(((int)*rp - (int)*pp) & 0xff);
  998.  
  999.       if (v < 128)
  1000.          s2 += v;
  1001.       else
  1002.          s2 += 256 - v;
  1003.  
  1004.       /* check avg filter */
  1005.       v = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff);
  1006.  
  1007.       if (v < 128)
  1008.          s3 += v;
  1009.       else
  1010.          s3 += 256 - v;
  1011.  
  1012.       /* check paeth filter */
  1013.       b = *pp;
  1014.       c = *cp;
  1015.       a = *lp;
  1016.       p = a + b - c;
  1017.       pa = abs(p - a);
  1018.       pb = abs(p - b);
  1019.       pc = abs(p - c);
  1020.  
  1021.       if (pa <= pb && pa <= pc)
  1022.          p = a;
  1023.       else if (pb <= pc)
  1024.          p = b;
  1025.       else
  1026.          p = c;
  1027.  
  1028.       v = (png_byte)(((int)*rp - p) & 0xff);
  1029.  
  1030.       if (v < 128)
  1031.          s4 += v;
  1032.       else
  1033.          s4 += 256 - v;
  1034.    }
  1035.  
  1036.    mins = s0;
  1037.    minf = 0;
  1038.  
  1039.    if (s1 < mins)
  1040.    {
  1041.       mins = s1;
  1042.       minf = 1;
  1043.    }
  1044.  
  1045.    if (s2 < mins)
  1046.    {
  1047.       mins = s2;
  1048.       minf = 2;
  1049.    }
  1050.  
  1051.    if (s3 < mins)
  1052.    {
  1053.       mins = s3;
  1054.       minf = 3;
  1055.    }
  1056.  
  1057.    if (s4 < mins)
  1058.    {
  1059.       mins = s4;
  1060.       minf = 4;
  1061.    }
  1062.  
  1063.    /* set filter byte */
  1064.    row[0] = minf;
  1065.  
  1066.    /* do filter */
  1067.    switch (minf)
  1068.    {
  1069.       /* sub filter */
  1070.       case 1:
  1071.          for (i = bpp, rp = row + (png_size_t)row_info->rowbytes,
  1072.             lp = row + (png_size_t)row_info->rowbytes - bpp;
  1073.             i < row_info->rowbytes; i++, rp--, lp--)
  1074.          {
  1075.             *rp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
  1076.          }
  1077.          break;
  1078.       /* up filter */
  1079.       case 2:
  1080.          for (i = 0, rp = row + (png_size_t)row_info->rowbytes,
  1081.             pp = prev_row + (png_size_t)row_info->rowbytes;
  1082.             i < row_info->rowbytes; i++, rp--, pp--)
  1083.          {
  1084.             *rp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
  1085.          }
  1086.          break;
  1087.       /* avg filter */
  1088.       case 3:
  1089.          for (i = row_info->rowbytes,
  1090.             rp = row + (png_size_t)row_info->rowbytes,
  1091.             pp = prev_row + (png_size_t)row_info->rowbytes,
  1092.             lp = row + (png_size_t)row_info->rowbytes - bpp;
  1093.             i > bpp; i--, rp--, lp--, pp--)
  1094.          {
  1095.             *rp = (png_byte)(((int)*rp - (((int)*lp + (int)*pp) /
  1096.                2)) & 0xff);
  1097.          }
  1098.          for (; i > 0; i--, rp--, pp--)
  1099.          {
  1100.             *rp = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
  1101.          }
  1102.          break;
  1103.       /* paeth filter */
  1104.       case 4:
  1105.          for (i = row_info->rowbytes,
  1106.             rp = row + (png_size_t)row_info->rowbytes,
  1107.             pp = prev_row + (png_size_t)row_info->rowbytes,
  1108.             lp = row + (png_size_t)row_info->rowbytes - bpp,
  1109.             cp = prev_row + (png_size_t)row_info->rowbytes - bpp;
  1110.             i > 0; i--, rp--, lp--, pp--, cp--)
  1111.          {
  1112.             int a, b, c, pa, pb, pc, p;
  1113.  
  1114.             b = *pp;
  1115.             if (i > bpp)
  1116.             {
  1117.                c = *cp;
  1118.                a = *lp;
  1119.             }
  1120.             else
  1121.             {
  1122.                a = c = 0;
  1123.             }
  1124.             p = a + b - c;
  1125.             pa = abs(p - a);
  1126.             pb = abs(p - b);
  1127.             pc = abs(p - c);
  1128.  
  1129.             if (pa <= pb && pa <= pc)
  1130.                p = a;
  1131.             else if (pb <= pc)
  1132.                p = b;
  1133.             else
  1134.                p = c;
  1135.  
  1136.             *rp = (png_byte)(((int)*rp - p) & 0xff);
  1137.          }
  1138.          break;
  1139.    }
  1140. }
  1141.  
  1142.